/**
 * Copyright (c) 2014- 2015 YCY Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.jkwzms.system.user.web.controller;

import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.alibaba.fastjson.JSON;
import com.jkwzms.common.Constants;
import com.jkwzms.common.entity.enums.BooleanEnum;
import com.jkwzms.common.entity.search.SearchRequest;
import com.jkwzms.common.entity.search.Searchable;
import com.jkwzms.common.inject.annotation.BaseComponent;
import com.jkwzms.common.pagination.Pagination;
import com.jkwzms.common.utils.EasyUiMsg;
import com.jkwzms.common.web.Servlets;
import com.jkwzms.common.web.bind.annotation.PageableDefaults;
import com.jkwzms.common.web.bind.annotation.SearchableDefaults;
import com.jkwzms.common.web.controller.BaseCRUDController;
import com.jkwzms.common.web.validate.ValidateResponse;
import com.jkwzms.system.organization.entity.Job;
import com.jkwzms.system.organization.entity.Organization;
import com.jkwzms.system.user.entity.User;
import com.jkwzms.system.user.entity.UserOrganizationJob;
import com.jkwzms.system.user.entity.UserStatus;
import com.jkwzms.system.user.service.UserService;
import com.jkwzms.system.user.web.bind.annotation.CurrentUser;
import com.jkwzms.system.utils.UserUitls;

/**
 * 用户Action
 * 
 * @author JackLiang
 * @date 2015-3-10
 * @version 1.0.0
 */
@Controller("adminUserController")
@RequestMapping(value = "/sys/user")
public class UserController extends BaseCRUDController<User, Long> {

    @Autowired
    @BaseComponent
    private UserService userService;

    @Override
    protected void setCommonData(Model model) {
        model.addAttribute("statusList", UserStatus.values());
        model.addAttribute("booleanList", BooleanEnum.values());
    }

    /***
     * 跳转到页面
     * 
     * @param model
     * @return
     */
    @RequestMapping(value = "main", method = RequestMethod.GET)
    public String main(Model model) {
        setCommonData(model);
        return "sys/user/list";
    }

    /**
     * @param model
     * @param user
     * @return
     */
    @RequestMapping(value = "show", method = RequestMethod.GET)
    public String show(Model model) {
        setCommonData(model);
        model.addAttribute("m", UserUitls.getCurrentUser());
        return viewName("userInfo");
    }

    /***
     * 跳转到页面
     * 
     * @param model
     * @return
     */
    @RequestMapping(value = "list", method = RequestMethod.GET)
    public String list(Model model) {
        return "sys/user/list";
    }

    /**
     * 已删除用户列表
     * 
     * @return
     */
    @RequestMapping(value = "delUserList", method = RequestMethod.GET)
    public String delUserList() {
        return "sys/user/delUserList";
    }

    /**
     * 已锁定用户列表
     * 
     * @return
     */
    @RequestMapping(value = "lockUserList", method = RequestMethod.GET)
    public String lockUserList() {
        return "sys/user/lockUserList";
    }

    @RequestMapping(value = "tree")
    public String tree(Model model) {
        return viewName("tree");
    }

    @RequestMapping(value = "list/discard")
    @PageableDefaults(sort = "id=desc")
    public Pagination<User> list(Searchable searchable, Model model) {
        throw new RuntimeException("discarded method");
    }

    /**
     * 获取分页查询数据
     * 
     * @param page
     * @param model
     * @return
     */
    @RequestMapping(value = { "" })
    @PageableDefaults(sort = "id=desc")
    @SearchableDefaults(value = "deleted_eq=0")
    @ResponseBody
    public Pagination<User> listAll(@RequestParam("page") int pageNumber, @RequestParam("rows") int pageSize,
                                    HttpServletRequest request, Model model) {
        setCommonData(model);

        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, Constants.SEARCH_PREFIX);
        Searchable searchable = SearchRequest.newSearchable();
        searchable.addSearchParams(searchParams);
        searchable.setPage(pageNumber - 1, pageSize);

        return userService.findAll(searchable);
    }

    /**
     * @param organization
     * @param job
     * @param pageNumber
     * @param pageSize
     * @param request
     * @return
     */
    @RequestMapping(value = { "{organization}/{job}" })
    @PageableDefaults(sort = "id=desc")
    @SearchableDefaults(value = "deleted_eq=0")
    @ResponseBody
    public Pagination<User> list(@PathVariable("organization") Organization organization, @PathVariable("job") Job job,
                                 @RequestParam("page") int pageNumber, @RequestParam("rows") int pageSize,
                                 HttpServletRequest request) {

        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, Constants.SEARCH_PREFIX);
        Searchable searchable = SearchRequest.newSearchable(searchParams);
        searchable.addSearchParams(searchParams);
        searchable.setPage(pageNumber, pageNumber);
        if (organization != null && !organization.isRoot()) {
            searchable.addSearchParam("organizationId", organization.getId());
        }
        if (job != null && !job.isRoot()) {
            searchable.addSearchParam("jobId", job.getId());
        }

        return super.list(pageNumber, pageSize, request);
    }

    @RequestMapping(value = "create/discard", method = RequestMethod.POST)
    @Override
    public Map<String, Object> create(Model model, @Valid @ModelAttribute("m") User m, BindingResult result,
                                      RedirectAttributes redirectAttributes) {
        throw new RuntimeException("discarded method");
    }

    @RequestMapping(value = "{id}/update/discard", method = RequestMethod.POST)
    @Override
    public String update(Model model, @Valid @ModelAttribute("m") User m, BindingResult result,
                         @RequestParam(value = Constants.BACK_URL, required = false) String backURL,
                         RedirectAttributes redirectAttributes) {
        throw new RuntimeException("discarded method");
    }

    /**
     * update user
     * 
     * @param model
     * @param m
     * @return
     */
    @RequestMapping(value = "update", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> update(Model model, @Valid @ModelAttribute("m") User m) {
        userService.update(m);
        return EasyUiMsg.successMsg(true);
    }

    /**
     * @param model
     * @param m
     * @param result
     * @param organizationIds
     * @param jobIds
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "create", method = RequestMethod.POST)
    public Map<String, Object> createWithOrganization(Model model,
                                                      @Valid @ModelAttribute("m") User m,
                                                      BindingResult result,
                                                      @RequestParam(value = "organizationId", required = false) Long[] organizationIds,
                                                      @RequestParam(value = "jobId", required = false) Long[][] jobIds,
                                                      RedirectAttributes redirectAttributes) {

        fillUserOrganization(m, organizationIds, jobIds);

        return super.create(model, m, result, redirectAttributes);
    }

    private void fillUserOrganization(User m, Long[] organizationIds, Long[][] jobIds) {
        if (ArrayUtils.isEmpty(organizationIds)) {
            return;
        }
        for (int i = 0, l = organizationIds.length; i < l; i++) {

            // 仅新增/修改一个 spring会自动split（“，”）--->给数组
            if (l == 1) {
                for (int j = 0, l2 = jobIds.length; j < l2; j++) {
                    UserOrganizationJob userOrganizationJob = new UserOrganizationJob();
                    userOrganizationJob.setOrganizationId(organizationIds[i]);
                    userOrganizationJob.setJobId(jobIds[j][0]);
                    m.addOrganizationJob(userOrganizationJob);
                }
            } else {
                Long[] jobId = jobIds[i];
                for (int j = 0, l2 = jobId.length; j < l2; j++) {
                    UserOrganizationJob userOrganizationJob = new UserOrganizationJob();
                    userOrganizationJob.setOrganizationId(organizationIds[i]);
                    userOrganizationJob.setJobId(jobId[j]);
                    m.addOrganizationJob(userOrganizationJob);
                }
            }

        }
    }

    @RequestMapping(value = "{id}/update", method = RequestMethod.POST)
    public String updateWithOrganization(Model model,
                                         @Valid @ModelAttribute("m") User m,
                                         BindingResult result,
                                         @RequestParam(value = "organizationId", required = false) Long[] organizationIds,
                                         @RequestParam(value = "jobId", required = false) Long[][] jobIds,
                                         @RequestParam(value = Constants.BACK_URL, required = false) String backURL,
                                         RedirectAttributes redirectAttributes) {

        fillUserOrganization(m, organizationIds, jobIds);

        return super.update(model, m, result, backURL, redirectAttributes);
    }

    /**
     * 修改密码
     * 
     * @param request
     * @param ids
     * @param newPassword
     * @param opUser
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "changePassword")
    @ResponseBody
    public Map<String, Object> changePassword(@RequestParam("newPassword") String newPassword, @CurrentUser User opUser) {
        User user = UserUitls.getCurrentUser();
        if (null == user) {
            return EasyUiMsg.ajaxMsg(Boolean.FALSE, "该用户不存在！");
        } else {
            userService.changePassword(opUser, user.getId(), newPassword);
            return EasyUiMsg.successMsg(true);
        }

    }

    /**
     * 改变状态
     * 
     * @param request
     * @param ids
     * @param newStatus
     * @param reason
     * @param opUser
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "changeStatus/{newStatus}")
    public String changeStatus(HttpServletRequest request, @RequestParam("ids") Long[] ids,
                               @PathVariable("newStatus") UserStatus newStatus, @RequestParam("reason") String reason,
                               @CurrentUser User opUser, RedirectAttributes redirectAttributes) {

        userService.changeStatus(opUser, ids, newStatus, reason);

        if (newStatus == UserStatus.normal) {
            redirectAttributes.addFlashAttribute(Constants.MESSAGE, "解封成功！");
        } else if (newStatus == UserStatus.blocked) {
            redirectAttributes.addFlashAttribute(Constants.MESSAGE, "封禁成功！");
        }

        return redirectToUrl((String) request.getAttribute(Constants.BACK_URL));
    }

    @RequestMapping(value = "recycle")
    public String recycle(HttpServletRequest request, @RequestParam("ids") Long[] ids,
                          RedirectAttributes redirectAttributes) {
        for (Long id : ids) {
            User user = userService.findOne(id);
            user.setDeleted(Boolean.FALSE);
            userService.update(user);
        }
        redirectAttributes.addFlashAttribute(Constants.MESSAGE, "还原成功！");
        return redirectToUrl((String) request.getAttribute(Constants.BACK_URL));
    }

    @RequestMapping("{user}/organizations")
    public String permissions(@PathVariable("user") User user) {
        return viewName("organizationsTable");
    }

    @RequestMapping("ajax/autocomplete")
    @PageableDefaults(value = 30)
    @ResponseBody
    public Set<Map<String, Object>> autocomplete(Searchable searchable, @RequestParam("term") String term) {

        return userService.findIdAndNames(searchable, term);
    }

    /**
     * 验证返回格式 单个：[fieldId, 1|0, msg] 多个：[[fieldId, 1|0, msg],[fieldId, 1|0, msg]]
     * 
     * @param fieldId
     * @param fieldValue
     * @return
     */
    @RequestMapping(value = "validate")
    @ResponseBody
    public Object validate(@RequestParam("fieldId") String fieldId, @RequestParam("fieldValue") String fieldValue,
                           @RequestParam(value = "id", required = false) Long id) {

        ValidateResponse response = ValidateResponse.newInstance();

        if ("username".equals(fieldId)) {
            User user = userService.findByUsername(fieldValue);
            if (user == null || (user.getId().equals(id) && user.getUsername().equals(fieldValue))) {
                // 如果msg 不为空 将弹出提示框
                response.validateSuccess(fieldId, "");
            } else {
                response.validateFail(fieldId, "用户名已被其他人使用");
            }
        }

        if ("email".equals(fieldId)) {
            User user = userService.findByEmail(fieldValue);
            if (user == null || (user.getId().equals(id) && user.getEmail().equals(fieldValue))) {
                // 如果msg 不为空 将弹出提示框
                response.validateSuccess(fieldId, "");
            } else {
                response.validateFail(fieldId, "邮箱已被其他人使用");
            }
        }

        if ("mobilePhoneNumber".equals(fieldId)) {
            User user = userService.findByMobilePhoneNumber(fieldValue);
            if (user == null || (user.getId().equals(id) && user.getMobilePhoneNumber().equals(fieldValue))) {
                // 如果msg 不为空 将弹出提示框
                response.validateSuccess(fieldId, "");
            } else {
                response.validateFail(fieldId, "手机号已被其他人使用");
            }
        }

        return response.result();
    }

}
